package com.javaeedev.dao.impl;

import java.util.List;
import java.util.UUID;

import com.javaeedev.dao.UserDao;
import com.javaeedev.domain.PasswordTicket;
import com.javaeedev.domain.User;
import com.javaeedev.exception.LockException;
import com.javaeedev.util.HibernateUtil;

public class UserDaoImpl implements UserDao {

    public User queryForSignOn(String username) {
        User user = queryUser(username);
        if(user.getLocked())
            throw new LockException(user.getLockDate());
        return user;
    }

    public User queryUser(String username) {
        return (User) HibernateUtil.query(User.class, username);
    }

    public void createUser(User user) {
        user.setEmailValidation((int)(Math.random() * 1000000) + 0xf);
        HibernateUtil.createEntity(user);
    }

    public void updateUser(User user) {
        HibernateUtil.updateEntity(user);
    }

    public boolean updateEmailValidation(String username, int ticket) {
        if(ticket==0)
            return false;
        return 1==HibernateUtil.executeUpdate(
                "update User as u set u.emailValidation=0 where u.username=? and u.emailValidation=?",
                new Object[] { username, ticket }
        );
    }

    public String createPasswordTicket(User user) {
        HibernateUtil.executeUpdate(
                "delete from PasswordTicket as pt where pt.user=?",
                new Object[] { user }
        );
        String ticket = UUID.randomUUID().toString().replaceAll("\\-", "");
        PasswordTicket pt = new PasswordTicket();
        pt.setUser(user);
        pt.setTicket(ticket);
        pt.setCreatedDate(System.currentTimeMillis());
        HibernateUtil.createEntity(pt);
        return ticket;
    }

    public boolean updatePassword(String username, String oldPassword, String newPassword) {
        if(!newPassword.matches(User.REGEX_PASSWORD))
            return false;
        return 1==HibernateUtil.executeUpdate(
                "update User as u set u.password=? where u.username=? and u.password=?",
                new Object[] { newPassword, username, oldPassword }
        );
    }

    public boolean queryResetPassword(User user, String ticket) {
        long time = System.currentTimeMillis() - 48L * 3600000L;
        return !HibernateUtil.queryForList(
                "select pt from PasswordTicket as pt where pt.user=? and pt.ticket=? and pt.createdDate>?",
                new Object[] { user, ticket, time}
        ).isEmpty();
    }

    @SuppressWarnings("unchecked")
    public boolean updateResetPassword(User user, String ticket, String password) {
        if(!password.matches(User.REGEX_PASSWORD))
            return false;
        long time = System.currentTimeMillis() - 48L * 3600000L;
        List<PasswordTicket> list = HibernateUtil.queryForList(
                "select pt from PasswordTicket as pt where pt.user=? and pt.ticket=? and pt.createdDate>?",
                new Object[] { user, ticket, time}
        );
        if(list.isEmpty())
            return false;
        HibernateUtil.executeUpdate(
                "delete from PasswordTicket as pt where pt.user=?",
                new Object[] { user }
        );
        HibernateUtil.executeUpdate(
                "update User as u set u.password=? where u.username=?",
                new Object[] { password, user.getUsername() }
        );
        return true;
    }

    public void updateLock(User user, long lockTime) {
        HibernateUtil.executeUpdate(
                "update User as u set u.lockDate=? where u.username=?",
                new Object[] { System.currentTimeMillis() + lockTime, user.getUsername() }
        );
    }

    public void updateUnlock(User user) {
        HibernateUtil.executeUpdate(
                "update User as u set u.lockDate=0 where u.username=?",
                new Object[] { user.getUsername() }
        );
    }

}
